package cn.pubinfo.commentapi.service.impl;

import cn.pubinfo.commentapi.model.Comment;
import cn.pubinfo.commentapi.service.CommentService;
import cn.pubinfo.commentapi.util.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author kuancz
 * @date 2018/7/24
 */
@Service
public class CommentServiceImpl implements CommentService {
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    private static final Logger logger = LoggerFactory.getLogger(CommentServiceImpl.class);

    @Override
    public List<Comment> list(String area, String category, Integer tourId, Integer page, Integer size, String start, String end) {
        List<Comment> commentList = new ArrayList<>();
        String key = area + ":" + category + ":" + tourId;
        int pageStart = (page - 1) * size;
        int pageEnd = page * size - 1;
        List<Long> duringList = parseDuring(start, end);
        Set<String> commentSet;
        if (duringList == null) {
            commentSet = redisTemplate.opsForZSet().range(key, pageStart, pageEnd);
        } else {
            commentSet = redisTemplate.opsForZSet().rangeByScore(key, duringList.get(0), duringList.get(1), pageStart, size);
        }
        if (commentSet == null) {
            return null;
        }
        commentSet.forEach(string -> {
            Comment comment = assemble(string);
            commentList.add(comment);
        });
        return commentList;
    }

    @Override
    public List<Comment> list(String area, String category, Integer page, Integer size, String start, String end) {
        return list(area, category, 0, page, size, start, end);
    }

    @Override
    public Long count(String area, String category) {
        String keyPattern = String.join(":", Arrays.asList(area, category)) + ":*";
        Set<String> stringSet = redisTemplate.keys(keyPattern);
        if (stringSet == null) {
            return 0L;
        }
        Long cnt = 0L;
        for (String key : stringSet) {
            Long size = redisTemplate.opsForZSet().size(key);
            cnt += size == null ? 0 : size;
        }
        return cnt;
    }

    @Override
    public Long count(String area, String category, Integer tourId) {
        String key = String.join(":", Arrays.asList(area, category, String.valueOf(tourId)));
        Long size = redisTemplate.opsForZSet().size(key);
        if (size == null) {
            return 0L;
        }
        return size;
    }

    /**
     * 装配comment对象
     *
     * @param info comment的redis中保存信息
     * @return comment
     * @author kun
     * @date 2018-07-25
     */
    private Comment assemble(Object info) {
        JSONObject jsonObject = JSONObject.parseObject(info.toString().replaceAll("\\\\[a-zA-Z0-9]*", ""));
        Comment comment = JSON.toJavaObject(jsonObject, Comment.class);
        comment.setTourId(jsonObject.getInteger("tour_id"));
        if (!"".equals(comment.getStar().trim()) && Double.parseDouble(comment.getStar()) >= 4) {
            comment.setPositive(true);
        }
        return comment;
    }

    /**
     * 获取时间段， 如果某一时间为空， 则用开始时间或者当前时间补上
     *
     * @param start 开始时间
     * @param end   结束时间
     * @author kun
     * @date 2018-07-26
     */
    private List<Long> parseDuring(String start, String end) {
        Long from = DateUtil.parseTimestamp(start);
        Long to = DateUtil.parseTimestamp(end);
        // 没有传入时间段参数
        if (from == null && to == null) {
            return null;
        }
        // 没有传入开始时间
        if (from == null) {
            from = -1 * DateUtil.parseTimestamp("1970-01-01") / 1000;
        }
        // 没有传入结束时间
        if (to == null) {
            to = -1 * System.currentTimeMillis() / 1000;
        }
        return Arrays.asList(to, from);
    }

}
